package com.kujie.access.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kujie.access.domain.po.ContractManagement;
import com.kujie.access.domain.query.ContractQuery;
import com.kujie.access.domain.vo.ContractManagementVO;
import com.kujie.access.mapper.ContractManagementMapper;
import com.kujie.access.service.IContractManagementService;
import com.kujie.common.core.domain.R;
import com.kujie.common.core.utils.StringUtils;
import com.kujie.common.excel.utils.ExcelUtil;
import com.kujie.common.mybatis.core.page.PageQuery;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 合同管理 api
 *
 * @author check
 * @date 2025-05-26
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ContractManagementServiceImpl implements IContractManagementService {
    private final ContractManagementMapper contractManagementMapper;

    @Override
    public Page<ContractManagementVO> list(ContractQuery contractQuery, PageQuery pageQuery) {
        Page<ContractManagementVO> result = pageQuery.build(new ContractManagementVO());
        LambdaQueryWrapper<ContractManagement> contractManagementLambdaQueryWrapper = new LambdaQueryWrapper<>();
        constructContractQuery(contractQuery, contractManagementLambdaQueryWrapper);

        Page<ContractManagement> contractManagementPage = contractManagementMapper.selectPage(pageQuery.build(), contractManagementLambdaQueryWrapper);
        if (CollectionUtils.isEmpty(contractManagementPage.getRecords())) {
            log.info("数据为空");
            return result;
        }

        List<ContractManagementVO> voList = contractManagementPage.getRecords().stream().map(e -> {
            ContractManagementVO contractManagementVO = new ContractManagementVO();
            BeanUtils.copyProperties(e, contractManagementVO);
            return contractManagementVO;
        }).toList();
        result.setTotal(contractManagementPage.getTotal());
        result.setRecords(voList);

        return result;
    }

    @Override
    public ContractManagement detail(Long id) {
        return contractManagementMapper.selectById(id);
    }

    @Override
    public int deleteByIds(List<Long> ids) {
        if (ids == null) {
            return 0;
        }
        return contractManagementMapper.deleteByIds(ids);
    }

    @Override
    public boolean insertOrUpdate(ContractManagement contractManagement) {
        ContractManagement management = contractManagementMapper.selectOne(new LambdaQueryWrapper<ContractManagement>().eq(ContractManagement::getContractUUID, contractManagement.getContractUUID()));
        if (management != null) {
            contractManagement.setId(management.getId());
        }
        return contractManagementMapper.insertOrUpdate(contractManagement);
    }

    @Override
    public List<ContractManagementVO> batchExport(ContractQuery contractQuery, HttpServletResponse response) {
        List<ContractManagement> contractManagements;

        // 判断是否全量导出
        if (!contractQuery.getIsAll()) {
            contractManagements = contractManagementMapper.selectByIds(contractQuery.getIds());
        } else {
            LambdaQueryWrapper<ContractManagement> contractManagementLambdaQueryWrapper = new LambdaQueryWrapper<>();
            constructContractQuery(contractQuery, contractManagementLambdaQueryWrapper);
            contractManagements = contractManagementMapper.selectList(contractManagementLambdaQueryWrapper);
        }

        return contractManagements.stream().map(e -> {
            ContractManagementVO contractManagementVO = new ContractManagementVO();
            BeanUtils.copyProperties(e, contractManagementVO);
            return contractManagementVO;
        }).toList();
    }

    @Override
    public R<?> batchImport(MultipartFile file) throws Exception {
        // 提取EXCEL的数据
        List<ContractManagementVO> contractManagementVOS = ExcelUtil.importExcel(file.getInputStream(), ContractManagementVO.class);
        if (CollectionUtils.isEmpty(contractManagementVOS)) {
            log.info("数据为空");
            return R.fail("excel为空");
        }

        LambdaQueryWrapper<ContractManagement> contractManagementLambdaQueryWrapper = new LambdaQueryWrapper<>();
        contractManagementLambdaQueryWrapper.in(ContractManagement::getContractUUID, contractManagementVOS.stream().map(ContractManagementVO::getContractUUID).toList());
        Map<String, ContractManagement> contractUuidToContract = contractManagementMapper.selectList(contractManagementLambdaQueryWrapper).stream().collect(Collectors.toMap(ContractManagement::getContractUUID, e -> e));

        // 获取批量插入的数据
        List<ContractManagement> insertList = contractManagementVOS.stream()
            .filter(e -> !contractUuidToContract.containsKey(e.getContractUUID()))
            .map(e -> {
                ContractManagement contractManagement = new ContractManagement();
                BeanUtils.copyProperties(e, contractManagement);
                return contractManagement;
            }).toList();

        // 获取批量更新的数据
        List<ContractManagement> updateList = contractManagementVOS.stream()
            .filter(e -> contractUuidToContract.containsKey(e.getContractUUID()))
            .map(e -> {
                ContractManagement contractManagement = new ContractManagement();
                contractManagement.setId(contractUuidToContract.get(e.getContractUUID()).getId());
                BeanUtils.copyProperties(e, contractManagement);
                return contractManagement;
            }).toList();

        StringBuilder errorMsg = new StringBuilder();
        Map<String, List<ContractManagement>> contractUuidToList = insertList.stream().collect(Collectors.groupingBy(ContractManagement::getContractUUID));
        contractUuidToList.forEach((key, value) -> {
            if (value.size() > 1) {
                errorMsg.append(key);
            }
        });

        if (StringUtils.isNotEmpty(errorMsg)) {
            return R.fail("excel数据有重复合同编号，请检查合同编号：[" + errorMsg + "]");
        }

        // 安全执行批量操作
        if (!CollectionUtils.isEmpty(insertList)) {
            contractManagementMapper.insertBatch(insertList);
        }
        if (!CollectionUtils.isEmpty(updateList)) {
            contractManagementMapper.updateBatchById(updateList);
        }
        return R.ok();
    }

    private void constructContractQuery(ContractQuery contractQuery, LambdaQueryWrapper<ContractManagement> contractManagementLambdaQueryWrapper) {
        contractManagementLambdaQueryWrapper.like(StringUtils.isNotEmpty(contractQuery.getContractUUID()), ContractManagement::getContractUUID, contractQuery.getContractUUID());
        contractManagementLambdaQueryWrapper.like(StringUtils.isNotEmpty(contractQuery.getContractName()), ContractManagement::getContractName, contractQuery.getContractName());
        contractManagementLambdaQueryWrapper.like(StringUtils.isNotEmpty(contractQuery.getPartyA()), ContractManagement::getPartyA, contractQuery.getPartyA());
        contractManagementLambdaQueryWrapper.like(StringUtils.isNotEmpty(contractQuery.getPartyB()), ContractManagement::getPartyB, contractQuery.getPartyB());
        contractManagementLambdaQueryWrapper.eq(StringUtils.isNotEmpty(contractQuery.getContractStatus()), ContractManagement::getContractStatus, contractQuery.getContractStatus());
        contractManagementLambdaQueryWrapper.ge(StringUtils.isNotEmpty(contractQuery.getSignStartDate()), ContractManagement::getContractCommencementDate, contractQuery.getSignStartDate());
        contractManagementLambdaQueryWrapper.le(StringUtils.isNotEmpty(contractQuery.getSignEndDate()), ContractManagement::getContractExpirationDate, contractQuery.getSignEndDate());
    }
}
